package com.ccp.dev.form.util;

import com.ccp.dev.core.util.BeanUtils;
import com.ccp.dev.core.util.StringPool;
import com.ccp.dev.core.util.StringUtil;
import com.ccp.dev.form.model.FormRights;
import net.sf.json.JSONObject;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.net.URL;
import java.util.*;


/**
 * ClassDescribe:
 * URL表单工具类
 * @author :wangcheng
 * Date: 2019-07-04
 */
public class UrlFormUtil {
    public static Map<String, List<JSONObject>> parseUrlHtml(String formKey, String baseUrl, HttpServletRequest request) throws Exception {
        String url = formKey;
        if (formKey.contains(StringPool.QUESTION_MARK)) {
            formKey = formKey.substring(0, formKey.indexOf(StringPool.QUESTION_MARK));
        }

        if (!formKey.contains(StringPool.PREFIX_URL)) {
            url = baseUrl + formKey;
        }

        Cookie[] cookies = request.getCookies();
        Connection conn = Jsoup.connect(url);
        for(Cookie cookie : cookies){
            conn.cookie(cookie.getName(),cookie.getValue());
        }

        Document doc = conn.timeout(3000).get();
        String baseUri = doc.baseUri();
        Map<String, List<JSONObject>> rightsMap = new HashMap<>(16);
        if (!baseUri.contains("login.html")) {
            Set<String> mainFieldSet = parseMainTable(doc);
            Map<Integer, Set<String>> subMap = parseSubTable(doc);
            rightsMap = getPermissionByUrlForm(doc.outerHtml(), mainFieldSet, subMap);
        }

        return rightsMap;
    }

    /**
     * 组装默认的url表单权限
     * @param html 文件html内容
     * @param mainFieldSet 主属性数据
     * @param subMap 子表数据
     * @return
     */
    private static Map<String, List<JSONObject>> getPermissionByUrlForm(String html, Set<String> mainFieldSet, Map<Integer, Set<String>> subMap) {
        Map<String, List<JSONObject>> map = new HashMap<>(16);

        // 主表字段权限
        List<JSONObject> fieldJsonList = new ArrayList<>();
        for (String field : mainFieldSet) {
            JSONObject permission = getPermissionJson(field,1);
            //增加字段的控件类型
            permission.put("controlType", "1");
            addDefaultPermission(permission);
            fieldJsonList.add(permission);
        }
        map.put("field", fieldJsonList);

        // 子表权限
        List<JSONObject> tableJsonList = new ArrayList<>();
        Set<Map.Entry<Integer, Set<String>>> mapSet = subMap.entrySet();
        for (Map.Entry<Integer, Set<String>> entry : mapSet) {
            // 子表整个表的权限
            String tableName = "subTable" + entry.getKey();
            JSONObject permission = FormUtil.getPermissionJson(tableName, tableName, 2);
            //每个子表中的每个字段
            List<JSONObject> subFieldJsonList = new ArrayList<>();
            for (String subField : entry.getValue()) {
                JSONObject subPermission = getPermissionJson(subField,1);

                //增加字段的控件类型
                subPermission.put("controlType", "1");

                subPermission.put("tableId", entry.getKey());
                subPermission.put("tableName", tableName);
                subPermission.put("mainTableId", "");
                subPermission.put("mainTableName", "");
                subFieldJsonList.add(subPermission);
            }
            permission.put("tableId", entry.getKey());
            permission.put("tableName", tableName);
            permission.put("mainTableId", "");
            permission.put("mainTableName", "");
            permission.put("subField", subFieldJsonList);
            tableJsonList.add(permission);
        }

        map.put("table", tableJsonList);

        // 意见权限。
        List<JSONObject> opinionJsonList = new ArrayList<>();
        Map<String, String> opinionMap = FormUtil.parseOpinion(html);
        Set<Map.Entry<String, String>> set = opinionMap.entrySet();
        for (Map.Entry<String, String> tmp : set) {
            JSONObject permission = FormUtil.getPermissionJson(tmp.getKey(), tmp.getValue(), 3);
            addDefaultPermission(permission);
            opinionJsonList.add(permission);
        }
        map.put("opinion", opinionJsonList);

        //子表显示与否
        List<JSONObject> tableShowJsonList = new ArrayList<>();
        for (Map.Entry<Integer, Set<String>> entry : mapSet) {
            String tableName = "subTable" + entry.getKey();
            JSONObject permission =  FormUtil.getPermissionJson(tableName, tableName, 4);
            permission.put("tableId", entry.getKey());
            permission.put("tableName", tableName);
            permission.put("mainTableId", "");
            permission.put("mainTableName", "");
            tableShowJsonList.add(permission);
        }

        map.put("tableShow", tableShowJsonList);

        return map;
    }

    /**
     * 添加默认权限
     * @param permission 权限列表
     */
    private static void addDefaultPermission(JSONObject permission) {
        permission.put("tableId", "");
        permission.put("tableName", "");
        permission.put("mainTableId", "");
        permission.put("mainTableName", "");
    }

    /**
     * 数据库存储的url表单权限解析返回到前台
     *
     * @param rightList 权限列表
     * @param formKey 表达定义id
     * @param baseUrl 基本url
     * @return Map<String, List<JSONObject>>
     * @throws Exception 异常抛出
     */
    public static Map<String, List<JSONObject>> getPermissionByUrlFormKey(List<FormRights> rightList, String formKey, String baseUrl, HttpServletRequest request) throws Exception {
        Map<String, List<JSONObject>> map = new HashMap<>(16);
        List<FormRights> formRightsList = new ArrayList<>();
        List<FormRights> tableRightsList = new ArrayList<>();
        List<FormRights> otherRightsList = new ArrayList<>();
        //子表显示与否
        List<FormRights> tableShowRightsList = new ArrayList<>();
        FormUtil.fillRightsList(rightList, formRightsList, tableRightsList, otherRightsList, tableShowRightsList);
        String url = formKey;

        // 去掉参数
        if (formKey.contains(StringPool.QUESTION_MARK)) {
            formKey = formKey.substring(0, formKey.indexOf(StringPool.QUESTION_MARK));
        }

        if (!formKey.contains(StringPool.PREFIX_URL)) {
            url = baseUrl + formKey;
        }

        Cookie[] cookies = request.getCookies();
        Connection conn = Jsoup.connect(url);
        for(Cookie cookie : cookies){
            conn.cookie(cookie.getName(),cookie.getValue());
        }
        Document doc = conn.timeout(3000).get();
        Set<String> mainFieldSet = parseMainTable(doc);
        Map<Integer, Set<String>> retMap = parseSubTable(doc);


        //主表字段权限
        List<JSONObject> fieldJsonList = new ArrayList<>();
        for (String mainField : mainFieldSet) {
            boolean mark = true;
            for (FormRights bpmFormRights : formRightsList) {
                if (!BeanUtils.isEmpty(bpmFormRights.getName()) && bpmFormRights.getName().equalsIgnoreCase(mainField.split(":")[0])) {
                    JSONObject permission = JSONObject.fromObject(bpmFormRights.getPermission());
                    if (!permission.containsKey("tableId")) {
                        // 增加控件类型
                        permission.put("controlType", "1");
                        addDefaultPermission(permission);
                    }
                    fieldJsonList.add(permission);
                    mark = false;
                    break;
                }
            }

            //没有设置过匹配权限权限时直接到初始化中获取(兼容以前版本)
            if (mark) {
                JSONObject permission = getPermissionJson(mainField, 1);
                // 增加控件类型
                permission.put("controlType", "1");
                addDefaultPermission(permission);
                fieldJsonList.add(permission);
            }
        }
        map.put("field", fieldJsonList);

        //子表字段权限
        List<JSONObject> tableJsonList = new ArrayList<>();
        Set<Map.Entry<Integer, Set<String>>> mapSet = retMap.entrySet();
        for (Map.Entry<Integer, Set<String>> entry : mapSet) {

            String tableName = "subTable" + entry.getKey();
            Integer tableId = entry.getKey();

            // 子表整个表的权限
            JSONObject permission = FormUtil.getPermissionJson(tableName, tableName, 2);
            //每个子表中的每个字段
            List<JSONObject> subFieldJsonList = new ArrayList<JSONObject>();
            for (String subField : entry.getValue()) {
                boolean mark = true;
                for (FormRights bpmFormRights : tableRightsList) {
                    if (!BeanUtils.isEmpty(bpmFormRights.getName()) && bpmFormRights.getName().equalsIgnoreCase(subField.split(":")[0])) {
                        JSONObject subPermission = JSONObject.fromObject(bpmFormRights.getPermission());
                        if (subPermission.containsKey("tableId") && subPermission.getString("tableId").equals(tableId.toString())) {
                            if (!subPermission.containsKey("mainTableId")) {

                                // 增加控件类型
                                subPermission.put("controlType", "1");

                                subPermission.put("tableId", tableId);
                                subPermission.put("tableName", tableName);
                                subPermission.put("mainTableId", "");
                                subPermission.put("mainTableName", "");
                            }
                            subFieldJsonList.add(subPermission);
                            mark = false;
                            break;
                        }
                    }
                }
                //没有设置过匹配权限时直接到初始化中获取(兼容以前版本)
                if (mark) {
                    JSONObject subPermission = FormUtil.getPermissionJson(subField, subField, 1);
                    //子表整个表的权限是重新生成的，所以不用判断

                    // 增加控件类型
                    subPermission.put("controlType", "1");

                    subPermission.put("tableId", tableId);
                    subPermission.put("tableName", tableName);
                    subPermission.put("mainTableId", "");
                    subPermission.put("mainTableName", "");
                    subFieldJsonList.add(subPermission);
                }
            }
            //子表整个表的权限是重新生成的，所以不用判断
            permission.put("tableId", tableId);
            permission.put("tableName", tableName);
            permission.put("mainTableId", "");
            permission.put("mainTableName", "");
            permission.put("subField", subFieldJsonList);
            tableJsonList.add(permission);
        }
        map.put("table", tableJsonList);

        //处理其它  意见权限。
        // 获取模版。
        String html = doc.outerHtml();
        List<JSONObject> opinionJsonList = new ArrayList<>();
        Map<String, String> opinionMap = FormUtil.parseOpinion(html);
        Set<Map.Entry<String, String>> set = opinionMap.entrySet();
        for (Iterator<Map.Entry<String, String>> it = set.iterator(); it.hasNext(); ) {
            boolean mark = true;
            Map.Entry<String, String> tmp = it.next();
            for (FormRights bpmFormRights : otherRightsList) {
                JSONObject opinionPermission = JSONObject.fromObject(bpmFormRights.getPermission());
                if (!BeanUtils.isEmpty(bpmFormRights.getName()) && bpmFormRights.getName().equalsIgnoreCase(tmp.getKey())) {
                    if (!opinionPermission.containsKey("tableId")) {
                        addDefaultPermission(opinionPermission);
                    }
                    opinionJsonList.add(opinionPermission);
                    mark = false;
                    break;
                }
            }
            //没有设置过匹配权限时直接到初始化中获取(兼容以前版本)
            if (mark) {
                JSONObject permission = FormUtil.getPermissionJson(tmp.getKey(), tmp.getValue(), 3);
                addDefaultPermission(permission);
                opinionJsonList.add(permission);
            }
        }
        map.put("opinion", opinionJsonList);

        //子表显示与否
        List<JSONObject> tableShowJsonList = new ArrayList<JSONObject>();
        for (Map.Entry<Integer, Set<String>> entry : mapSet) {
            String tableName = "subTable" + entry.getKey();
            Integer tableId = entry.getKey();
            boolean mark = true;
            for (FormRights bpmFormRights : tableShowRightsList) {
                if (!BeanUtils.isEmpty(bpmFormRights.getName()) && bpmFormRights.getName().equalsIgnoreCase(tableName)) {
                    JSONObject permission = JSONObject.fromObject(bpmFormRights.getPermission());
                    if (!permission.containsKey("tableId")) {
                        permission.put("tableId", tableId);
                        permission.put("tableName", tableName);
                        permission.put("mainTableId", "");
                        permission.put("mainTableName", "");
                    }
                    tableShowJsonList.add(permission);
                    mark = false;
                    break;
                }
            }
            //没有设置过匹配权限权限时直接到初始化中获取(兼容以前版本)
            if (mark) {
                JSONObject permission = FormUtil.getPermissionJson(tableName, tableName, 4);
                permission.put("tableId", tableId);
                permission.put("tableName", tableName);
                permission.put("mainTableId", "");
                permission.put("mainTableName", "");
                tableShowJsonList.add(permission);
            }
        }
        map.put("tableShow", tableShowJsonList);

        return map;
    }

    /**
     * 解析子表
     * @param doc 文件内容
     * @return 属性数据
     */
    public static Map<Integer, Set<String>> parseSubTable(Document doc) {
        Elements subTableList = doc.select("div[type^=subtable]");
        Map<Integer, Set<String>> retMap = new HashMap<>(16);
        int count = 0;
        for (Element el : subTableList) {
            Elements els = el.children().select("input[name^=s:],textarea[name^=s:],select[name^=s:]");
            Set<String> subFieldSet = getElementName(els);
            count++;
            retMap.put(count, subFieldSet);
        }
        return retMap;
    }

    /**
     * 解析主表
     * @param doc 文件内容
     * @return 属性列表
     */
    public static Set<String> parseMainTable(Document doc) {
        Elements elemList = doc.select("input,textarea,select");
        Elements mList = doc.select("input[name^=m:],textarea[name^=m:],select[name^=m:]");
        // 如果时代码生成的表单，解析name^=m的字段
        if (mList.size() > 0) {
            elemList = mList;
        }
        return getElementName(elemList);
    }

    /**
     * 找到元素的名称
     * @param elemList 元素列表
     * @return 属性列表
     */
    private static Set<String> getElementName(Elements elemList) {
        Set<String> fieldSet = new HashSet<>();
        for (Element el : elemList) {
            String name = el.attr("name");
            //input的类型
            String type = el.attr("type");
            Element td = el.parent().previousElementSibling();
            if ("checkbox".equals(type) || "radio".equals(type)) {
                td = el.parent().parent().previousElementSibling();
            }
            name += ":" + td.text();
            //名字做成"标签名:显示名"的格式
            /*if (StringUtil.isEmpty(name)) {
                Element td = el.parent().previousElementSibling();
                if ("checkbox".equals(type) || "radio".equals(type)) {
                    td = el.parent().parent().previousElementSibling();
                }
                name = td.text().replaceAll(":", "");
            }*/

            /*if (!"button".equals(type) && !"hidden".equals(type)) {
                // 获取字段名
                String fieldName = name.replaceAll("^.*:", "").toLowerCase();
                fieldSet.add(fieldName);
            }*/
            fieldSet.add(name);
        }
        return fieldSet;
    }

    public static JSONObject getPermissionJson(String title, int type) {
        String[] strs = title.split(":");
        String defJson = "{type:'everyone',id:'', fullname:''}";
        JSONObject json = new JSONObject();
        json.element("title", strs[0]);
        json.element("memo", strs[1]);
        if (type != FormRights.TABLE_SHOW_RIGHTS) {
            json.element("read", defJson);
            json.element("write", defJson);
            if (type != FormRights.TABLE_RIGHTS) {
                json.element("required", "{type:'none',id:'', fullname:''}");
            }
        } else {
            //子表显示可写：w  子表显示只读：r  为显示  其它为隐藏（y）   可以增加默认
            json.element("show", "{addBtn:'true'}");
        }
        return json;
    }
}
